/********************************************************************************
 * Project Name		[JavaEE_JDBC]
 * File Name     	[Database.java]
 * Creation Date 	[2015-01-01]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ********************************************************************************/
package _notes;

/**
 * 数据库相关概念
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 * 
 */
public final class Database {

	public void transactionFeatures() {
		/**
		 * 事务的四大特性[ACID]<br/>
		 * 
		 * 原子性[Atomicity]<br/>
		 * 原子性是指事务是一个不可分割的工作单位, 事务中的操作要么全部成功, 要么全部失败<br/>
		 * 比如在同一个事务中的SQL语句, 要么全部执行成功, 要么全部执行失败<br/>
		 * 
		 * 一致性[Consistency]<br/>
		 * 一致性是指事务必须使数据库从一个一致性状态变换到另外一个一致性状态<br/>
		 * 以转账为例子, A向B转账, 若转账之前这两个用户的金额加起来总共是1000, 那么A向B转账之后, 不管这两个账户怎么转,
		 * A用户的金额和B用户的金额加起来的总额还是1000<br/>
		 * 
		 * 隔离性[Isolation]<br/>
		 * 隔离性是指多个用户并发访问数据库时, 数据库为每个用户开启的事务不能被其他事务的操作数据所干扰, 多个并发事务之间要相互隔离<br/>
		 * 
		 * 持久性[Durability]<br/>
		 * 持久性是指一个事务一旦被提交, 它对数据库中数据的改变就是永久性的, 接下来即使数据库发生故障也不应该对其有任何影响<br/>
		 */
	}

	public void isolationIssues() {
		/**
		 * 脏读[Dirty Read]: 指一个事务读取了另外一个事务未提交的数据<br/>
		 * 
		 * 例如A向B转帐100元, 对应SQL语句如下所示 :<br/>
		 * <code>
		 * UPDATE account SET balance = balance + 100 WHERE name = 'B';
		 * UPDATE account SET balance = balance - 100 WHERE name = 'A';
		 * </code><br/>
		 * 当第1条SQL执行完, 第2条还没执行[A未提交时], 如果此时B查询自己的帐户, 就会发现自己多了100元钱, 如果A等B走后再回滚,
		 * B就会损失100元<br/>
		 * 
		 * 不可重复读[Unrepeatable Read]: 指在一个事务内多次相同的查询返回的结果不一致<br/>
		 * 
		 * 例如银行查询A帐户余额, 第一次查询A帐户为100元, 此时A向帐户内存了100元并提交了, 银行接着又进行了一次查询,
		 * 此时A帐户为200元了 , 银行两次查询不一致<br/>
		 * 不可重复读和脏读的区别是, 脏读是读取前一事务未提交的脏数据, 不可重复读是重新读取了前一事务已提交的数据<br/>
		 * 可能导致的问题: 比如银行程序需要将查询结果分别输出到电脑屏幕和写到文件中, 结果在一个事务中针对输出的目的地进行的两次查询不一致,
		 * 导致文件和屏幕中的结果不一致, 银行工作人员无法判断正确结果<br/>
		 * 
		 * 幻读[phantom read]: 指在一个事务内读取到了别的事务插入的数据, 导致前后读取不一致<br/>
		 * 
		 * 例如第一个事务对一个表中的数据进行了修改, 这种修改涉及到表中的全部数据行, 同时第二个事务也修改这个表中的数据,
		 * 这种修改是向表中插入一行新数据, 那么就会发生操作第一个事务的用户发现表中还有没有修改的数据行, 就好象发生了幻觉一样<br/>
		 */
	}

	public void isolationLevels() {
		/**
		 * MySQL的隔离级别[由高到低]<br/>
		 * Serializable[串行化]: 可避免脏读, 不可重复读, 幻读情况的发生<br/>
		 * Repeatable read[可重复读]: 可避免脏读, 不可重复读情况的发生<br/>
		 * Read committed[读已提交]: 可避免脏读情况发生<br/>
		 * Read uncommitted[读未提交]: 以上情况均无法保证<br/>
		 * 
		 * MySQL查看数据库隔离级别: select @@tx_isolation<br/>
		 * MySQL默认的数据库隔离级别: Repeatable read<br/>
		 * MySQL设置数据库隔离级别: set transaction isolation level read committed
		 */
	}
}
